<?php
// +----------------------------------------------------------------------
// | A3Mall
// +----------------------------------------------------------------------
// | Copyright (c) 2020 http://www.a3-mall.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: xzncit <158373108@qq.com>
// +----------------------------------------------------------------------
namespace app\api\controller\wap;

use app\common\model\Calculation;
use app\common\model\users\AccountDetails;
use app\common\model\users\AccountLevelLimit;
use app\common\model\users\AccoutBind;
use app\common\model\users\Recharge;
use app\common\model\users\UsersKey;
use app\common\model\users\UsersLog;
use app\common\model\users\Wallet;
use app\common\model\users\WalletDetail;
use app\common\model\users\WithdrawLog;
use app\model\User;
use mall\basic\Area;
use mall\basic\Payment;
use mall\library\alipay\AlipayService;
use mall\library\payex\PayexService;
use mall\utils\Check;
use mall\utils\CString;
use mall\utils\Tool;
use think\Exception;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\Filesystem;
use think\facade\Log;
use think\facade\Request;
use mall\basic\Users;
use think\Image;
use mall\basic\Token;
use function GuzzleHttp\Psr7\_caseless_remove;

class Ucenter extends Base {


    /**
     * 获取 vip 有效期 的字符串
     * @param int $expire
     */
    private function getVipExpireStr(int $expire) {
        return  $expire?date('Y-m-d H:i',$expire):'';
    }

    /**
     * 激活 VIP
     * @return \think\response\Json
     */
    public function activate_vip() {
        try{

            // 获取参数
            $params = \request()->post();
            foreach (['vip','type','money','vip_expire'] as $field) {
                if(!array_key_exists($field,$params)) {
                    throw new Exception('参数错误');
                }
            }

            // 用户模型类
            $userModel = new \app\common\model\users\Users();

            // 获取并验证套餐价格
            $vipPackage = $userModel::vipPackage();
            $vipPackage = array_combine(array_column($vipPackage,'type'),array_column($vipPackage,'money'));
            if(!array_key_exists($params['type'],$vipPackage) || bccomp($vipPackage[$params['type']],$params['money'],20) !== 0) {
                throw new Exception('数据更新，请刷新重试');
            }

            // 判断用户数据
            if(!$userDetails = $userModel->field(['id','vip','vip_expire','local_balance','local_consume'])->find(Users::get('id'))) {
                throw new Exception('数据错误，请刷新重试');
            }
            $userDetails = $userDetails->getData();

            if($userDetails['vip'] != $params['vip'] || $this->getVipExpireStr($userDetails['vip_expire']) != $params['vip_expire']) {
                throw new Exception('数据更新，请刷新重试');
            }

            // 验证余额
            if(bccomp($vipPackage[$params['type']],$userDetails['local_balance'],$userModel::AMOUNT_SCALE) == 1) {
                throw new Exception('余额不足，请先充值');
            }


            Db::startTrans();
            try {
                // 开通会员，并进行计费处理
                if(!$userModel->vipRenew($userDetails,$params['type'],$vipPackage[$params['type']]) || !($userDetails = $userModel->field(['vip','vip_expire'])->find(Users::get('id')))) {
                    throw new Exception('数据更新，请刷新重试');
                }
                Db::commit();

            }catch (\Exception $e) {
                Db::rollback();
                throw $e;
            }

            return $this->returnAjax("ok",1,[
                'vip'   => $userDetails['vip'],
                'vip_expire'    => $this->getVipExpireStr($userDetails['vip_expire']),
                'vip_effective' => true,
            ]);
        }catch (\Exception $e){
            return $this->returnAjax(Tool::getErrorMessage($e),0);
        }
    }


    /**
     * 账户详情日志
     */
    public function account_log() {
        $type = Request::get('type',1,'intval');
        $page = Request::get('page',1,'intval');
        $pageSize = Request::get('pagesize',15,'intval');
        $where = [
            'user_id'   => \mall\basic\Users::get('id')
        ];
        if($type > 0) {
            $where['type'] = $type;
        }
        $data['list'] = array_map(function($value){
            $value['date'] = date('Y-m-d H:i:s',$value['create_time']);
            $value['money'] = Calculation::trimZero($value['money'],6);
            return $value;
        },
            (new AccountDetails())->recordAll($where,[($page-1)*$pageSize,$pageSize],['account_details_id'=>'DESC'],['money','type','create_time'])
        );
        return $this->returnAjax("ok",1,$data);
    }

    //个人信息
    public function info(){
        $info = Db::name("users")->where('id',Users::get("id"))->find();

        return $this->returnAjax("ok",1,[
            "username"=>$info["username"],
            "nickname"=>$info["nickname"],
            "mobile"=>$info["mobile"],
            "amount"=>$info["amount"],
            "avatar"=>Users::avatar($info["avatar"]),
            "local_balance"=> Calculation::trimZero($info['local_balance'],4),
            'vip'   => $info['vip'],
            'vip_expire'=> $this->getVipExpireStr($info['vip_expire']),
            'vip_effective' => \app\common\model\users\Users::isVip($info),
            'min_balance'   => \app\common\model\users\Users::balanceMinLimit($info),
        ]);
    }

    //我得钱包
    public function wallet(){
        $info = Db::name("wallet")->where('user_id',Users::get("id"))->find();

        if(empty($info)) {
            $data = [
                'total_amout'=>0,
                'withdraw_amount'=>0,
                'non_withdraw_amount'=>0,
            ];
        } else {
            $data = [
                'total_amout'=>$info['total_amout'],
                'withdraw_amount'=>$info['withdraw_amount'],
                'non_withdraw_amount'=>$info['non_withdraw_amount'],
            ];
        }
        $data['is_recharge'] = false;
        return $this->returnAjax("ok",1,$data);
    }

    //充值
    public function recharge() {
        try{
            $params = array_map(function($value){return trim($value);},Request::post());
            validate([
                'amount'   => 'require|float|>:0',
                'channel'   => 'require|min:1|max:4',
                'source_account'  =>  'require',
            ],[
                'amount'  =>  '充值金额必须大于 0',
                'channel'   =>  '充值渠道非法',
                'source_account'  => '请输入支付账号',
            ])->check($params);

            $params['user_id'] = Users::get("id");
            $params['charge_no'] = time().rand(10000,99999);
            (new Recharge())->save($params);
            $data = [];
            switch ($params['channel']){
                //如果是支付宝
                case 1:
                    $data['redirect'] = Request::host().'/api/ucenter/recharge_redirect?charge_no='.$params['charge_no'].'&amount='.$params['amount'];
                    break;
                //微信
                case 2:
                //payex
                case 3:
                    $payexService =  new PayexService([
                        'returnUrl' => Request::domain().'/api/ucenter/recharge_callback?goto=' . urlencode('http://mjdk.dfx666.com/#/index?id=3'),
                        'notifyUrl' => Request::domain().'/api/ucenter/recharge_callback?charge_no='.$params['charge_no'] . '&channel=3',
                    ]);

                    // 获取用户信息
                    $userDetails = (new \app\common\model\users\Users())->find(Users::get('id'));
                    $payexService->setApiParams([
                        'amount'    => $params['amount'],
                        'customer_name' => empty($userDetails->realname)?$userDetails->nickname:$userDetails->realname,
                        'contact_number'    =>  $userDetails->mobile,
                        'email'    => $userDetails->email,
                    ]);
                    $data['redirect'] = Request::host().'/api/ucenter/recharge_redirect?goto=' . urlencode($payexService->doPayUrl());
                    break;
            }
            return $this->returnAjax("充值成功",1,$data);
        }catch (\Exception $e) {
            return $this->returnAjax(Tool::getErrorMessage($e),0);
        }
    }



    //充值回调
    public function rechargeRedirect() {
        if($goto = Request::get('goto')) {
            return redirect($goto)->send();
        }
        $params = array_map(function($value){return trim($value);},Request::request());
        try{
            Log::write($params,'notice');
            /*** 请填写以下配置信息 ***/
            $appid = '2021002125699282';  //https://open.alipay.com 账户中心->密钥管理->开放平台密钥，填写添加了电脑网站支付的应用的APPID
            $returnUrl = 'http://mjdk.dfx666.com/#/index?id=3'; //付款成功后的同步回调地址
            //付款成功后的异步回调地址
            $notifyUrl = Request::host().'/api/ucenter/recharge_callback?charge_no='.$params['charge_no'];
            $outTradeNo = $params['charge_no'];     //你自己的商品订单号
            $payAmount = $params['amount'];          //付款金额，单位:元
            $orderName = '充值';    //订单标题
            $signType = 'RSA2';			//签名算法类型，支持RSA2和RSA，推荐使用RSA2
            $rsaPrivateKey= config('pay.alipay_private_key');
            /*** 配置结束 ***/
            $aliPay = new AlipayService();
            $aliPay->setAppid($appid);
            $aliPay->setReturnUrl($returnUrl);
            $aliPay->setNotifyUrl($notifyUrl);
            $aliPay->setRsaPrivateKey($rsaPrivateKey);
            $aliPay->setTotalFee($payAmount);
            $aliPay->setOutTradeNo($outTradeNo);
            $aliPay->setOrderName($orderName);
            $sHtml = $aliPay->doPay();
            echo $sHtml;exit;
            //return $this->returnAjax("ok",1,[]);
        }catch (\Exception $e) {
            return $this->returnAjax(Tool::getErrorMessage($e),0);
        }
    }

    //充值回调
    public function rechargeCallback() {
        if($goto = Request::get('goto')) {
            return redirect($goto)->send();
        }
        $params = array_map(function($value){return trim($value);},Request::request());
        try{
            Log::write('回调数据','notice');
            Log::write($params,'notice');
            Db::startTrans();

            if(isset($params['charge_no']) && $this->rechargeCallbackValidate($params)) {
                Log::write('更新状态','notice');
                $rechargeInfo = Db::name("recharge")->where([
                    'charge_no'=>$params['charge_no'],
                    'status'    => 0,
                ])->find();
                if(isset($rechargeInfo['user_id'])) {
                    $wallet = (new Wallet())->findOne($rechargeInfo['user_id'])->toArray();
                    //增加钱包明细
                    (new WalletDetail())->recordAddToWallet($wallet,$rechargeInfo['amount'],'recharge',['related_id'=>$rechargeInfo['id']]);
                    //更新充值状态为完成
                    (new Recharge())::update(['status'=>1],['charge_no'=>$params['charge_no'],'status'=>0]);
                }
            }
            Db::commit();
            return $this->returnAjax("ok",1,[]);
        }catch (\Exception $e) {
            Db::rollback();
            return $this->returnAjax(Tool::getErrorMessage($e),0);
        }
    }


    /**
     * 支付验证（简单字段验证，并无实际验证）
     * @param array $params
     * @return bool
     */
    private function rechargeCallbackValidate(array $params)
    {
        if(array_key_exists('response',$params) && array_key_exists('txn_id',$params) && array_key_exists('signature',$params)) {  // 判断为 payex支付
            if(!( new PayexService())->signatureValidate($params['signature'],$params['txn_id'])) { // 验证签名
                return false;
            }
            Log::write('payex signature OK','notice');

            switch (strtoupper(trim($params['response']))) {
                case 'APPROVED':    // 通过支付
                    return true;
            }
        } else if(array_key_exists('trade_status',$params)) {
            switch (strtoupper(trim($params['trade_status']))) {
                case 'TRADE_SUCCESS':    // 通过支付
                    return true;
            }
        }

        return false;

    }

    //提现
    public function withDraw(){
        try{
            $params = array_map(function($value){return trim($value);},Request::post());
            validate([
                'amount'   => 'require|float|>:0',
                'channel'   => 'require|min:1|max:4',
                'payee_account'  =>  'require',
            ],[
                'amount'  =>  '提现金额必须大于 0',
                'channel'   =>  '提现渠道非法',
                'payee_account'  => '请输入收款账号',
            ])->check($params);

            $params['user_id'] = Users::get("id");
            Db::startTrans();
            $withdrawLog = (new WithdrawLog());
            $withdrawLog->save($params);
            $wallet = (new Wallet())->findOne($params['user_id'])->toArray();
            if($wallet['withdraw_amount']<=$params['amount']){
                return $this->returnAjax("可提现余额不足",0,[]);
            }
            //增加钱包明细
            //(new WalletDetail())->recordAddToWallet($wallet,bcsub(0,$params['amount'],2),'withDraw',['related_id'=>$withdrawLog->id]);
            (new Wallet())->updateFromWalletDetaisl(Users::get("id"),$wallet['ver'],-$params['amount'],0);
            Db::commit();
            return $this->returnAjax("申请提现成功，请等待管理员审核",1,[]);
        }catch (\Exception $e) {
            Db::rollback();
            return $this->returnAjax(Tool::getErrorMessage($e),0);
        }
    }

    //绑定钥匙
    public function keyBind(){
        try{
            //$uid = Users::get("id");
            $params = array_map(function($value){return trim($value);},Request::post());
            validate([
                'platform'   => 'require|min:1|max:3',
                'access_key'  =>  'require',
                'secret_key'  =>  'require',
            ],[
                'platform'   =>  '类型非法',
                'access_key'  => '请输入账户api_key',
                'secret_key'  => '请输入账户secret_key',
            ])->check($params);
            $params['user_id'] = Users::get("id");
            $accountId = (new UsersKey())->getAccountId($params['access_key'],$params['secret_key']);
            if($accountId) {
                $params['account_id'] = $accountId;
            } else {
                return $this->returnAjax("api_key或secret_key不正确",0,[]);
            }

            $isBind = (new UsersKey())->withSearch(['platform','access_key','secret_key'], [
                'access_key' => $params['access_key'],
                'secret_key' => $params['secret_key'],
                'platform'		=>	isset($params['platform'])?$params['platform']:1
            ])->count();
            if($isBind) {
                return $this->returnAjax("该钥匙对已经被其他账号绑定，请解绑后再绑定",0,[]);
            }
            $count = (new UsersKey())->withSearch(['user_id','platform'], [
                'user_id'	=>	Users::get("id"),
                'platform'		=>	isset($params['platform'])?$params['platform']:1
            ])->count();
            if($count>0) {
                (new UsersKey())::update($params,['user_id'=>Users::get("id"),'platform'=>$params['platform']]);
                return $this->returnAjax("更新绑定成功",1,[]);
            } else {
                $params['id'] = Users::get("id");
                //(new UsersKey())->save($params);
                (new UsersKey())->insert($params);
                return $this->returnAjax("绑定成功",1,[]);
            }

        }catch (\Exception $e){
            return $this->returnAjax(Tool::getErrorMessage($e),0);
        }
    }

    //获取钥匙对列表
    public function keyList(){
        try{
            $params = array_map(function($value){return trim($value);},Request::get());
            $params['user_id'] = Users::get("id");
            $list = (new UsersKey())->withSearch(['user_id','platform'], [
                'user_id'	=>	$params['user_id'],
                'platform'	=>	isset($params['platform'])?$params['platform']:1
            ])->select();
            $data['list'] = $list?$list->toArray():[];

            return $this->returnAjax("ok",1,$data);
        }catch (\Exception $e){
            return $this->returnAjax(Tool::getErrorMessage($e),0);
        }
    }

    //删除钥匙对
    public function delKey(){
        try{
            $params = array_map(function($value){return trim($value);},Request::get());
            $user_id = Users::get("id");
            (new UsersKey())->where('user_id',$user_id)->delete();
            return $this->returnAjax("ok",1);
        }catch (\Exception $e){
            return $this->returnAjax(Tool::getErrorMessage($e),0);
        }
    }


    //退出登录
    public function loginOut(){
        try{
            // 添加退出日志
            UsersLog::logAdd('LOGIN_OUT',[]);

            Token::delete(Users::get("id"));
            return $this->returnAjax("退出成功",1,[]);
        }catch (\Exception $e){
            return $this->returnAjax(Tool::getErrorMessage($e),0);
        }
    }

    public function help(){
        return $this->returnAjax("ok",1, array_map(function($res){
            $res["content"] = Tool::replaceContentImage(Tool::removeContentAttr($res["content"]));
            return $res;
        },$archives = Db::name("archives")->where([
            "pid"=>"70"
        ])->select()->toArray()));
    }


}
